package net.hserver.admin.system.exception;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.hserver.core.ioc.annotation.Component;
import cn.hserver.mvc.context.WebContext;
import cn.hserver.mvc.exception.GlobalExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import net.hserver.admin.system.common.MyCode;
import net.hserver.admin.system.common.MyException;
import net.hserver.admin.system.common.MyResult;
import org.yaml.snakeyaml.constructor.DuplicateKeyException;

@Component
@Slf4j
public class ResponseException extends GlobalExceptionHandler {

    @Override
    public void handlerException(Throwable throwable, WebContext webContext) {
        MyException exception = getException(throwable, MyException.class);
        if (exception!=null) {
            log.error("「 ".concat(exception.getMessage()).concat(" 」\n"), exception);
            webContext.response.sendJson(exception.getResult());
            return;
        }
        NotLoginException e = getException(throwable, NotLoginException.class);
        if (e!=null) {
            MyResult result = MyResult.failure();
            result.setCode(MyCode.NOT_LOGIN);
            String message = switch (e.getType()) {
                case NotLoginException.NOT_TOKEN -> "未能读取到有效 token";
                case NotLoginException.INVALID_TOKEN -> "token 无效";
                case NotLoginException.TOKEN_TIMEOUT -> "token 已过期";
                case NotLoginException.BE_REPLACED -> "token 已被顶下线";
                case NotLoginException.KICK_OUT -> "token 已被踢下线";
                default -> "当前会话未登录";
            };
            result.setMessage(message);
            log.error("「 ".concat(message).concat(" 」\n"), e);
            webContext.response.sendJson(result);
            return;
        }

        MyResult result = MyResult.failure();
        if (getException(throwable,DuplicateKeyException.class)!=null) {
            result.setCode(MyCode.DUPLICATE_KEY);
        } else if (getException(throwable,NullPointerException.class)!=null) {
            result.setCode(MyCode.NPE);
        } else if (getException(throwable,NotPermissionException.class)!=null || getException(throwable,NotRoleException.class)!=null) {
            result.setCode(MyCode.ACCESS_DENIED);
        } else {
            result.setCode(MyCode.SERVER_ERROR);
        }
        log.error("「 ".concat(result.getMessage()).concat(" 」\n"), throwable);
        webContext.response.sendJson(result.setException(throwable.getLocalizedMessage()));
    }
}
